//! Jaeger追踪管理器测试
//! 
//! 包含完整的单元测试、集成测试和性能测试

use super::*;
use std::collections::HashMap;
use tokio_test;

/// 测试Jaeger追踪管理器创建
#[tokio::test]
async fn test_jaeger_manager_creation() {
    let config = JaegerConfig::default();
    // 注意：这个测试可能失败，因为没有真实的Jaeger服务器
    // 但我们可以测试配置和代码路径
    match JaegerTracingManager::new(config).await {
        Ok(_) => println!("Jaeger追踪管理器创建成功"),
        Err(e) => println!("Jaeger追踪管理器创建失败（可能预期）: {}", e),
    }
}

/// 测试配置默认值
#[test]
fn test_default_config() {
    let config = JaegerConfig::default();
    assert_eq!(config.agent_endpoint, "http://localhost:14268/api/traces");
    assert_eq!(config.service_name, "data-gateway");
    assert_eq!(config.service_version, "0.1.0");
    assert_eq!(config.environment, "development");
    assert_eq!(config.sampling_rate, 1.0);
    assert_eq!(config.batch_size, 512);
    assert_eq!(config.export_timeout, 30);
    assert_eq!(config.enable_console, true);
    assert_eq!(config.enable_json, false);
    assert_eq!(config.max_attributes, 128);
}

/// 测试Span状态枚举
#[test]
fn test_span_status_enum() {
    // 测试相等性
    assert_eq!(SpanStatus::InProgress, SpanStatus::InProgress);
    assert_eq!(SpanStatus::Ok, SpanStatus::Ok);
    assert_eq!(SpanStatus::Error, SpanStatus::Error);
    assert_eq!(SpanStatus::Cancelled, SpanStatus::Cancelled);
    
    // 测试不相等性
    assert_ne!(SpanStatus::Ok, SpanStatus::Error);
    assert_ne!(SpanStatus::InProgress, SpanStatus::Cancelled);
    
    // 测试序列化
    let json = serde_json::to_string(&SpanStatus::Ok).unwrap();
    assert_eq!(json, "\"Ok\"");
    
    let json = serde_json::to_string(&SpanStatus::Error).unwrap();
    assert_eq!(json, "\"Error\"");
}

/// 测试追踪统计信息
#[test]
fn test_tracing_stats() {
    let stats = TracingStats::default();
    assert_eq!(stats.total_spans, 0);
    assert_eq!(stats.exported_spans, 0);
    assert_eq!(stats.failed_spans, 0);
    assert_eq!(stats.avg_span_duration_ms, 0.0);
    assert!(stats.last_export_time.is_none());
    assert!(stats.service_stats.is_empty());
}

/// 测试服务统计信息
#[test]
fn test_service_stats() {
    let stats = ServiceStats::default();
    assert_eq!(stats.request_count, 0);
    assert_eq!(stats.error_count, 0);
    assert_eq!(stats.avg_response_time_ms, 0.0);
    assert!(stats.last_activity.is_none());
}

/// 测试Span信息创建
#[test]
fn test_span_info_creation() {
    let mut tags = HashMap::new();
    tags.insert("service.name".to_string(), "test-service".to_string());
    tags.insert("operation.type".to_string(), "query".to_string());
    
    let span_info = SpanInfo {
        span_id: "test-span-id".to_string(),
        trace_id: "test-trace-id".to_string(),
        operation_name: "test_operation".to_string(),
        start_time: chrono::Utc::now(),
        end_time: None,
        duration_ms: None,
        tags,
        status: SpanStatus::InProgress,
    };
    
    assert_eq!(span_info.span_id, "test-span-id");
    assert_eq!(span_info.trace_id, "test-trace-id");
    assert_eq!(span_info.operation_name, "test_operation");
    assert_eq!(span_info.status, SpanStatus::InProgress);
    assert!(span_info.end_time.is_none());
    assert!(span_info.duration_ms.is_none());
    assert_eq!(span_info.tags.len(), 2);
    assert_eq!(span_info.tags.get("service.name"), Some(&"test-service".to_string()));
}

/// 测试配置序列化和反序列化
#[test]
fn test_config_serialization() {
    let config = JaegerConfig {
        agent_endpoint: "http://test:14268/api/traces".to_string(),
        service_name: "test-service".to_string(),
        service_version: "1.0.0".to_string(),
        environment: "production".to_string(),
        sampling_rate: 0.5,
        batch_size: 1024,
        export_timeout: 60,
        enable_console: false,
        enable_json: true,
        max_attributes: 256,
    };
    
    // 测试序列化
    let json = serde_json::to_string(&config).unwrap();
    assert!(json.contains("test-service"));
    assert!(json.contains("production"));
    assert!(json.contains("0.5"));
    
    // 测试反序列化
    let deserialized: JaegerConfig = serde_json::from_str(&json).unwrap();
    assert_eq!(deserialized.agent_endpoint, config.agent_endpoint);
    assert_eq!(deserialized.service_name, config.service_name);
    assert_eq!(deserialized.service_version, config.service_version);
    assert_eq!(deserialized.environment, config.environment);
    assert_eq!(deserialized.sampling_rate, config.sampling_rate);
    assert_eq!(deserialized.batch_size, config.batch_size);
    assert_eq!(deserialized.export_timeout, config.export_timeout);
    assert_eq!(deserialized.enable_console, config.enable_console);
    assert_eq!(deserialized.enable_json, config.enable_json);
    assert_eq!(deserialized.max_attributes, config.max_attributes);
}

/// 测试Span信息序列化
#[test]
fn test_span_info_serialization() {
    let mut tags = HashMap::new();
    tags.insert("service.name".to_string(), "test-service".to_string());
    
    let span_info = SpanInfo {
        span_id: "span-123".to_string(),
        trace_id: "trace-456".to_string(),
        operation_name: "database_query".to_string(),
        start_time: chrono::Utc::now(),
        end_time: Some(chrono::Utc::now()),
        duration_ms: Some(150.5),
        tags,
        status: SpanStatus::Ok,
    };
    
    // 测试序列化
    let json = serde_json::to_string(&span_info).unwrap();
    assert!(json.contains("span-123"));
    assert!(json.contains("trace-456"));
    assert!(json.contains("database_query"));
    assert!(json.contains("150.5"));
    
    // 测试反序列化
    let deserialized: SpanInfo = serde_json::from_str(&json).unwrap();
    assert_eq!(deserialized.span_id, span_info.span_id);
    assert_eq!(deserialized.trace_id, span_info.trace_id);
    assert_eq!(deserialized.operation_name, span_info.operation_name);
    assert_eq!(deserialized.duration_ms, span_info.duration_ms);
    assert_eq!(deserialized.status, span_info.status);
    assert_eq!(deserialized.tags.len(), 1);
}

/// 测试追踪统计信息序列化
#[test]
fn test_tracing_stats_serialization() {
    let mut service_stats = HashMap::new();
    service_stats.insert("test-service".to_string(), ServiceStats {
        request_count: 100,
        error_count: 5,
        avg_response_time_ms: 25.5,
        last_activity: Some(chrono::Utc::now()),
    });
    
    let stats = TracingStats {
        total_spans: 1000,
        exported_spans: 950,
        failed_spans: 50,
        avg_span_duration_ms: 75.2,
        last_export_time: Some(chrono::Utc::now()),
        service_stats,
    };
    
    // 测试序列化
    let json = serde_json::to_string(&stats).unwrap();
    assert!(json.contains("1000"));
    assert!(json.contains("950"));
    assert!(json.contains("75.2"));
    
    // 测试反序列化
    let deserialized: TracingStats = serde_json::from_str(&json).unwrap();
    assert_eq!(deserialized.total_spans, stats.total_spans);
    assert_eq!(deserialized.exported_spans, stats.exported_spans);
    assert_eq!(deserialized.failed_spans, stats.failed_spans);
    assert_eq!(deserialized.avg_span_duration_ms, stats.avg_span_duration_ms);
    assert_eq!(deserialized.service_stats.len(), 1);
}

/// 测试UUID生成
#[test]
fn test_uuid_generation() {
    let uuid1 = uuid::Uuid::new_v4().to_string();
    let uuid2 = uuid::Uuid::new_v4().to_string();
    
    // UUID应该是不同的
    assert_ne!(uuid1, uuid2);
    
    // UUID应该有正确的格式
    assert_eq!(uuid1.len(), 36);
    assert_eq!(uuid2.len(), 36);
    
    // 应该包含连字符
    assert!(uuid1.contains('-'));
    assert!(uuid2.contains('-'));
}

/// 性能测试：Span创建
#[test]
fn test_span_creation_performance() {
    let start = std::time::Instant::now();
    
    for i in 0..1000 {
        let mut tags = HashMap::new();
        tags.insert("iteration".to_string(), i.to_string());
        
        let _span_info = SpanInfo {
            span_id: uuid::Uuid::new_v4().to_string(),
            trace_id: uuid::Uuid::new_v4().to_string(),
            operation_name: format!("operation_{}", i),
            start_time: chrono::Utc::now(),
            end_time: None,
            duration_ms: None,
            tags,
            status: SpanStatus::InProgress,
        };
    }
    
    let duration = start.elapsed();
    assert!(duration.as_millis() < 1000, "Span创建性能测试失败，耗时: {:?}", duration);
}

/// 边界条件测试
#[test]
fn test_edge_cases() {
    // 测试空标签
    let span_info = SpanInfo {
        span_id: "test".to_string(),
        trace_id: "test".to_string(),
        operation_name: "test".to_string(),
        start_time: chrono::Utc::now(),
        end_time: None,
        duration_ms: None,
        tags: HashMap::new(),
        status: SpanStatus::InProgress,
    };
    assert_eq!(span_info.tags.len(), 0);
    
    // 测试极端采样率
    let config1 = JaegerConfig {
        sampling_rate: 0.0,
        ..Default::default()
    };
    assert_eq!(config1.sampling_rate, 0.0);
    
    let config2 = JaegerConfig {
        sampling_rate: 1.0,
        ..Default::default()
    };
    assert_eq!(config2.sampling_rate, 1.0);
    
    // 测试极端批次大小
    let config3 = JaegerConfig {
        batch_size: 1,
        ..Default::default()
    };
    assert_eq!(config3.batch_size, 1);
    
    let config4 = JaegerConfig {
        batch_size: 10000,
        ..Default::default()
    };
    assert_eq!(config4.batch_size, 10000);
}

/// 并发测试
#[tokio::test]
async fn test_concurrent_span_operations() {
    // 创建多个并发任务
    let mut handles = vec![];
    for i in 0..10 {
        let handle = tokio::spawn(async move {
            let mut tags = HashMap::new();
            tags.insert("task_id".to_string(), i.to_string());
            
            let span_info = SpanInfo {
                span_id: uuid::Uuid::new_v4().to_string(),
                trace_id: uuid::Uuid::new_v4().to_string(),
                operation_name: format!("concurrent_operation_{}", i),
                start_time: chrono::Utc::now(),
                end_time: None,
                duration_ms: None,
                tags,
                status: SpanStatus::InProgress,
            };
            
            // 模拟一些工作
            tokio::time::sleep(tokio::time::Duration::from_millis(10)).await;
            
            span_info.span_id
        });
        handles.push(handle);
    }
    
    // 等待所有任务完成
    let mut span_ids = Vec::new();
    for handle in handles {
        let span_id = handle.await.unwrap();
        span_ids.push(span_id);
    }
    
    // 验证所有Span ID都是唯一的
    assert_eq!(span_ids.len(), 10);
    for i in 0..span_ids.len() {
        for j in i + 1..span_ids.len() {
            assert_ne!(span_ids[i], span_ids[j]);
        }
    }
}

/// 集成测试：完整的追踪流程
#[test]
fn test_tracing_integration() {
    // 创建配置
    let config = JaegerConfig {
        service_name: "integration-test".to_string(),
        environment: "test".to_string(),
        sampling_rate: 1.0,
        ..Default::default()
    };
    
    // 验证配置
    assert_eq!(config.service_name, "integration-test");
    assert_eq!(config.environment, "test");
    assert_eq!(config.sampling_rate, 1.0);
    
    // 创建Span信息
    let mut tags = HashMap::new();
    tags.insert("service.name".to_string(), config.service_name.clone());
    tags.insert("environment".to_string(), config.environment.clone());
    
    let start_time = chrono::Utc::now();
    let span_info = SpanInfo {
        span_id: uuid::Uuid::new_v4().to_string(),
        trace_id: uuid::Uuid::new_v4().to_string(),
        operation_name: "integration_test".to_string(),
        start_time,
        end_time: Some(start_time + chrono::Duration::milliseconds(100)),
        duration_ms: Some(100.0),
        tags,
        status: SpanStatus::Ok,
    };
    
    // 验证Span信息
    assert_eq!(span_info.operation_name, "integration_test");
    assert_eq!(span_info.status, SpanStatus::Ok);
    assert_eq!(span_info.duration_ms, Some(100.0));
    assert!(span_info.end_time.is_some());
    
    // 验证标签
    assert_eq!(span_info.tags.get("service.name"), Some(&"integration-test".to_string()));
    assert_eq!(span_info.tags.get("environment"), Some(&"test".to_string()));
}
